package embuzzled.g5;

import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;

import embuzzled.ui.Grid;
import embuzzled.ui.GridSolution;
import embuzzled.ui.Player;

public class G5Player implements Player{
	
	public Color[][] initPuzzles(Color[][] map) {
		
		// F I V E
		//PuzzleSet five = new PuzzleSet(20,3);
		
		// F
		SingleColorPuzzle f = new SingleColorPuzzle(3,3);
		boolean[][] fa = {
				{true, true, true},
				{true, true, false},
				{true, false, false}
		};
		f.setColorMap(fa);
		f.setColor(Color.PINK);
		
		Color[][] fLocal = f.returnLocalColorMap();
		
		// I
		SingleColorPuzzle i = new SingleColorPuzzle(3,3);
		boolean[][] fi = {
				{false, true, false},
				{false, true, false},
				{false, true, false}
		};
		i.setColorMap(fi);
		i.setColor(Color.BLUE);
		Color[][] iLocal = i.returnLocalColorMap();
		
		// V
		SingleColorPuzzle v = new SingleColorPuzzle(3,3);
		boolean[][] fv = {
				{true, false, true},
				{true, false, true},
				{false, true, false}
		};
		v.setColorMap(fv);
		v.setColor(Color.MAGENTA);
		Color[][] vLocal = v.returnLocalColorMap();
		
		// E
		SingleColorPuzzle e = new SingleColorPuzzle(3,3);
		boolean[][] fe = {
				{true, true, true},
				{true, true, false},
				{true, true, true}
		};
		e.setColorMap(fe);
		e.setColor(Color.ORANGE);
		Color[][] eLocal = e.returnLocalColorMap();
		
		//Place puzzle
		int rows = map.length;
		int cols = map[0].length;
		
		ArrayList<Color[][]> fiveArray = new ArrayList<Color[][]>();
		fiveArray.add(fLocal);
		fiveArray.add(iLocal);
		fiveArray.add(vLocal);
		fiveArray.add(eLocal);
	
		
		
		boolean placed = false;
		boolean placeV = false;
		int r = 0;
		int c = 0;
		int letter = 0;
		
		Color[][] currentMap = map;
		
		while(!placed)
		{
			System.out.println("Adding letter " + (letter + 1));
			//nullCheck(currentMap);
			Color[][] newMap = superimpose(currentMap, fiveArray.get(letter), new Point(c,r));
			
			if(newMap != null)
			{
				System.out.println("Successfully added letter");
				currentMap = newMap;
				letter++;
				r+= 5;
			}
			else if(r > map[0].length)
			{
				System.out.println("No possible moves");
				placed = true;
				placeV = true;
			}
			else if(newMap == null && letter == 0 && c < map.length)
			{
				System.out.println("Can't add first. Check next col.");
				c++;
			}
			else if(newMap == null && letter == 0 && c == map.length)
			{
				System.out.println("Can't add first. Check next row.");
				c = 0;
				r++;
			}
			else if(newMap == null && letter != 0)
			{
				System.out.println("Can't add letter. Check next row.");
				r++;
			}
			else
			{
				throw new IllegalStateException("Can't place this");
			}
			
			if(letter == fiveArray.size())
			{
				System.out.println("Added whole word.");
				placed = true;
			}
		}
		
		if(placeV)
		{
			c = 0;
			r = 0;
			currentMap = map;
		}
		
		
		while(placeV)
		{
			System.out.println("Adding V");
			
			Color[][] newMap = superimpose(currentMap, vLocal, new Point(c,r));
			
			if(newMap != null)
			{
				System.out.println("Successfully added letter");
				currentMap = newMap;
				letter++;
				r+= 5;
				placeV = false;
			}
			else if(r > map[0].length)
			{
				System.out.println("No possible moves");
				continue;
			}
			else if(newMap == null && c < map.length)
			{
				System.out.println("Can't add first. Check next col.");
				c++;
			}
			else if(newMap == null && c == map.length)
			{
				System.out.println("Can't add first. Check next row.");
				c = 0;
				r++;
			}
			else if(newMap == null)
			{
				System.out.println("Can't add letter. Check next row.");
				r++;
			}
			else
			{

				throw new IllegalStateException("Can't place this");
			}
			
		}
		
		return currentMap;
		
		/*five.add(f);
		five.add(i);
		five.add(v);
		five.add(e);*/
		
		//five.assignColors();
		
	}
	/**
	 * Attempt to place color map "part" onto color map "whole" at point p.
	 * Returns the combined color map if possible, null if not.
	 * @param whole
	 * @param part
	 * @param p
	 * @return
	 */
	public Color[][] superimpose(Color[][] whole, Color[][] part, Point p)
	{
		int x = p.x;
		int y = p.y;
		
		int localRows = part.length;
		int localCols = part[0].length;
		
		int xMax = p.x + localCols;
		int yMax = p.y + localRows;
		
		System.out.println("Adding a " +  localCols + "x" + localRows +
				" puzzle to a " + whole[0].length + "x" + whole.length +
				" map at location (" + x + ", " + y + ")");
		
		//Sanity check. Part would fall off the edge of whole.
		if(xMax > whole[0].length)
			return null;
		if(yMax > whole.length)
			return null;
		
		Color[][] newMap = new Color[whole.length][whole[0].length];
		
		for(int r = 0; r < localRows; r++)
			for(int c = 0; c < localCols; c++)
			{
				int wholeR = r + p.y;
				int wholeC = c + p.x;
				
				System.out.println("Checking (" + wholeR + ", " + wholeC + ")");
				
				boolean isWholeClear = whole[wholeR][wholeC].equals(Constants.COLOR_CLEAR);
				boolean isPartClear = part[r][c].equals(Constants.COLOR_CLEAR);
				
				if(isPartClear)
				{
					//Not coloring this cell, keep old color.
					System.out.println("Don't need to color");
					newMap[wholeR][wholeC] = whole[wholeR][wholeC];
				}
				else if(isWholeClear)
				{
					//Color in a previously clear cell.
					System.out.println("Color in cell using " + part[r][c]);
					newMap[wholeR][wholeC] = part[r][c];
				}
				else if(!isWholeClear)
				{
					//Attempting to recolor an already colored cell.
					return null;
				}
			}
		
		//Copy the rest of the previous color map.
		for(int r = 0; r < newMap.length; r++)
			for(int c = 0; c < newMap[0].length; c++)
			{
				if(newMap[r][c] == null)
					newMap[r][c] = whole[r][c];
			}
		
		return newMap;
	}
	
	public void nullCheck(Color[][] map)
	{
		for(int r = 0; r < map.length; r++)
			for(int c = 0; c < map[0].length; c++)
			{
				if(map[r][c] == null)
					System.out.println("Row " + r + " and column " + c + " is null");
			}
	}
	
	public Color[][] generateInitialColorMap(Grid grid)
	{
		int rows = grid.rows;
		int cols = grid.cols;
		
		Color[][] map = new Color[rows][cols];
		
		for(int i = 0; i < rows; i++)
			for(int j = 0; j < cols; j++)
			{
				if(grid.datagrid[i][j])
					map[i][j] = Constants.COLOR_OBSTACLE;
				else
					map[i][j] = Constants.COLOR_CLEAR;
			}
		
		return map;
	}

	public GridSolution move(Grid grid) {
		// hardcode
		
		System.out.println("Move");
		
		/*Color[][] initialPuzzle = generateInitialColorMap(grid);
		
		Color[][] placedPuzzles = initPuzzles(initialPuzzle);*/
		
		/* Initialize grid, puzzles. Populate grid with puzzles. */
		PuzzleGrid g = new PuzzleGrid(grid);
		PuzzleSet g5Puzzles = new G5Puzzles();
		g.populate(g5Puzzles);
		
		/* Create a solution */
        //throw new UnsupportedOperationException("Not supported yet.");
        int rows = grid.rows;
        int cols = grid.cols;
        int no_of_puz = g.numPuzzles;
        String SolutionKey = g.solution;
        GridSolution DumbSolution = new GridSolution(rows, cols, no_of_puz,SolutionKey);

        DumbSolution.GridColors = g.grid;
        
        /* Create a background */
        for(int loopr=0;loopr<rows;loopr++)
        {
            for(int loopc=0;loopc<cols;loopc++)
            {
                Color tempc = DumbSolution.GridColors[loopr][loopc];
                //Color in only clear cells.
                if (tempc.equals(Constants.COLOR_CLEAR)) 
                {
					if ((loopr + loopc) % 2 == 0) 
					{
						tempc = new Color(255, 0, 0);
					} 
					else 
					{
						tempc = new Color(0, 255, 0);
					}
				}
				DumbSolution.GridColors[loopr][loopc] = tempc;

            }

        }
       
        //System.out.println("I was called");
        return DumbSolution;

    }

}

